<?php 
class DomArOneToManyTestCase extends DomArTestUnitTestCase { 
	
	public function testConstruct() {
		$a = new DomArOneToManyTestClass('a');
		$c = new DomArOneToManyChildTestClass('c');
		
		$prop = $a->getProperty('children');
		$this->assertIdentical( $prop->childClassName, 'DomArOneToManyChildTestClass');
		$this->assertIdentical( $prop->className, 'DomArOneToManyTestClass' );
		$this->assertIdentical( $prop->inverse, 'parent' );
		$this->assertIdentical( $prop->actAsParent, true );
		$this->assertIdentical( $prop->composition, true );
		
		$prop = $c->getProperty('parent');
		$this->assertIdentical( $prop->childClassName, 'DomArOneToManyTestClass');
		$this->assertIdentical( $prop->className, 'DomArOneToManyChildTestClass' );
		$this->assertIdentical( $prop->inverse, 'children' );
		$this->assertIdentical( $prop->actAsParent, false );
		$this->assertIdentical( $prop->composition, false );
		
		
		
		$prop = $a->getProperty('aggrChildren');
		$this->assertIdentical( $prop->childClassName, 'DomArOneToManyChildTestClass');
		$this->assertIdentical( $prop->className, 'DomArOneToManyTestClass' );
		$this->assertIdentical( $prop->inverse, 'aggrParent' );
		$this->assertIdentical( $prop->actAsParent, true );
		$this->assertIdentical( $prop->composition, false );
		
		$prop = $c->getProperty('aggrParent');
		$this->assertIdentical( $prop->childClassName, 'DomArOneToManyTestClass');
		$this->assertIdentical( $prop->className, 'DomArOneToManyChildTestClass' );
		$this->assertIdentical( $prop->inverse, 'aggrChildren' );
		$this->assertIdentical( $prop->actAsParent, false );
		$this->assertIdentical( $prop->composition, false );
		
		
		
		$prop = $a->getProperty('parents');
		$this->assertIdentical( $prop->childClassName, 'DomArOneToManyChildTestClass');
		$this->assertIdentical( $prop->className, 'DomArOneToManyTestClass' );
		$this->assertIdentical( $prop->inverse, 'child' );
		$this->assertIdentical( $prop->actAsParent, false );
		$this->assertIdentical( $prop->composition, false );
		
		$prop = $c->getProperty('child');
		$this->assertIdentical( $prop->childClassName, 'DomArOneToManyTestClass');
		$this->assertIdentical( $prop->className, 'DomArOneToManyChildTestClass' );
		$this->assertIdentical( $prop->inverse, 'parents' );
		$this->assertIdentical( $prop->actAsParent, true );
		$this->assertIdentical( $prop->composition, false );
		
		
		
		$this->assertEqual( $a->access('children'), NULL );
		$this->assertTrue( $a->children instanceof DomArSet );
		
			
	}
	
	public function testBasics() {
		
		DomArOneToManyTestClass::getTable()->update();
		
		$a1 = new DomArOneToManyTestClass('a1');
		$a2 = new DomArOneToManyTestClass('a2');
		
		$b = new DomArOneToManyChildTestClass('b');
		$c = new DomArOneToManyChildTestClass('c');

		$a1->children[] = $b;
		$a1->children[] = $c;

		$a1->save();
		
		$this->assertTrue( $a1->id > 0 );
		$this->assertTrue( $b->id > 0 );
		$this->assertTrue( $c->id > 0 );
		
		$this->assertObjectDatabaseValue( $b, 'parent', $a1->id );
		$this->assertObjectDatabaseValue( $c, 'parent', $a1->id );

		DomAr::flushStoredObjects();
		
		$aa1 = DomArOneToManyTestClass::load( $a1->id );
		
		$aa1->delete();

		$this->assertTableEmpty( $a1->getTableName() );
		$this->assertTableEmpty( $b->getTableName() );

	}
	
	public function testRemove() {
		
		DomArOneToManyTestClass::getTable()->update();
		
		$a1 = new DomArOneToManyTestClass('a1');
		
		$b = new DomArOneToManyChildTestClass('b');
		$c = new DomArOneToManyChildTestClass('c');

		$a1->children[] = $b;
		$a1->children[] = $c;

		$this->assertEqual( count($a1->children->getNewObjects()), 2);

		$a1->children->remove( $b );
		$this->assertEqual( count($a1->children->getNewObjects()), 1);
		$this->assertIdentical( $b->parent, NULL );

		$a1->children[] = $b;

		$a1->save();
		
		$this->assertEqual( $a1->children->count(), 2);
		
		$a1->children->remove( $b );
		$this->assertIdentical( $b->parent, NULL );
		$this->assertEqual( $a1->children->count(), 1);
	}
	
	/**
	 * This test tests that if item gets removed from list and it has some listeners that change object that these changes get saved!
	 */
	public function testRemove2() {
		DomArOneToManyRemove::getTable()->update();
		
		$a = new DomArOneToManyRemove();
		$b = new DomArOneToManyRemove();

		$a->items[] = $b;
		
		$a->save();
		
		$this->assertTrue( $a->id > 0 );
		$this->assertTrue( $b->id > 0 );
		$this->assertTrue( $b->hasParent );
		$this->assertEqual( $a->itemsCount, 1 );
		
		// removing b
		$b->parent = NULL;
		$this->assertEqual( $a->itemsCount, 0 );
		$this->assertFalse( $b->hasParent );
		
		DomAr::flushStoredObjects();
		
		$a = DomArOneToManyRemove::load( $a->id );
		$b = DomArOneToManyRemove::load( $b->id );
		
		$this->assertEqual( $a->itemsCount, 0 );
		$this->assertTrue( $b->hasParent ); // @tricky this must be true, as $b is not saved!
		$this->assertIdentical( $b->parent, NULL );
		$this->assertIdentical( $a->items->count(), 0);
		
		// TESTING OTHERWAY AROUND
		
		$a = new DomArOneToManyRemove();
		$b = new DomArOneToManyRemove();	
		$a->items[] = $b;
		$a->save();
		
		$a->items->remove( $b );
		$this->assertEqual( $a->itemsCount, 0 );
		$this->assertFalse( $b->hasParent );
		
		DomAr::flushStoredObjects();
		
		$a = DomArOneToManyRemove::load( $a->id );
		$b = DomArOneToManyRemove::load( $b->id );
		
		$this->assertEqual( $a->itemsCount, 1 ); // @tricky this must be 1 as $a is not saved!
		$this->assertFalse( $b->hasParent );
		$this->assertIdentical( $b->parent, NULL );
		$this->assertIdentical( $a->items->count(), 0);
		
	}
	
	public function testSet() {
		
		DomArOneToManyTestClass::getTable()->update();
		
		$a1 = new DomArOneToManyTestClass('a1');
		$a2 = new DomArOneToManyTestClass('a2');
		
		$b = new DomArOneToManyChildTestClass('b');
		$c = new DomArOneToManyChildTestClass('c');
		$d = new DomArOneToManyChildTestClass('d');
		$e = new DomArOneToManyChildTestClass('e');
		$f = new DomArOneToManyChildTestClass('f');
		
		$a1->children[] = $b;
		$c->parent = $a1;
		
		$this->assertIdentical( $b->parent, $a1);
		$this->assertIdentical( $c->parent, $a1);
		$children = $a1->children->getNewObjects();
		
		$this->assertIdentical( $children[0], $b);
		$this->assertIdentical( $children[1], $c);
		$this->assertIdentical( count($children), 2);
		
		$a1->save();
		$this->assertObjectDatabaseValue( $b, 'parent', $a1->id );
		$this->assertObjectDatabaseValue( $c, 'parent', $a1->id );
		
		
		// test replace 
		$b->parent = $a2;
		
		$this->assertIdentical( $b->parent, $a2);
		$this->assertIdentical( $c->parent, $a1);
		
		$children = $a1->children->query()->commit()->toArray();
		$this->assertTrue( $c->id > 0 );
		$this->assertIdentical( $children[0]->id, $c->id);
		$this->assertIdentical( count($children), 1);
		
		$children = $a2->children->getNewObjects();
		$this->assertIdentical( $children[0], $b);
		$this->assertIdentical( count($children), 1);
		
		
		
	}
	
	public function testReAdding() {
		DomArOneToManyListener::getTable()->update();
		
		$a = new DomArOneToManyListener();
		$b = new DomArOneToManyListener();
		
		// reset A
		$a->reset();
		$b->reset();
		$this->assertIdentical( $a->beforeAddCount, 0 );
		$this->assertIdentical( $a->afterAddCount, 0 );
		$this->assertIdentical( $b->beforeSetCount, 0 );
		$this->assertIdentical( $b->afterSetCount, 0 );
		
		// -------------------------------
		// ADD ITEM (unsaved)
		$a->items[] = $b;
		$this->assertIdentical( $a->beforeAddCount, 1 );
		$this->assertIdentical( $a->afterAddCount, 1 );
		$this->assertIdentical( $b->beforeSetCount, 1 );
		$this->assertIdentical( $b->afterSetCount, 1 );
		
		// -------------------------------
		// SAVE AND RELOAD
		$a->save();
		$a->items[] = $b;
		$this->assertIdentical( $a->beforeAddCount, 1 );
		$this->assertIdentical( $a->afterAddCount, 1 );
		$this->assertIdentical( $b->beforeSetCount, 1 );
		$this->assertIdentical( $b->afterSetCount, 1 );
		
		DomAr::flushStoredObjects();
		$a = DomArOneToManyListener::load( $a->id );
		$b = DomArOneToManyListener::load( $b->id );
		$a->reset();
		$b->reset();
		
		// -------------------------------
		// ADD ITEM AGAIN (saved)
		$a->items[] = $b;
		$this->assertIdentical( $a->beforeAddCount, 0 );
		$this->assertIdentical( $a->afterAddCount, 0 );
		$this->assertIdentical( $b->beforeSetCount, 0 );
		$this->assertIdentical( $b->afterSetCount, 0 );
		
		
		// -------------------------------
		// TEST parent saved and child not
		$a = new DomArOneToManyListener();
		$b = new DomArOneToManyListener();
		$a->save();
		
		// ADD ITEM
		$a->items[] = $b;
		$this->assertIdentical( $a->beforeAddCount, 1 );
		$this->assertIdentical( $a->afterAddCount, 1 );
		$this->assertIdentical( $b->beforeSetCount, 1 );
		$this->assertIdentical( $b->afterSetCount, 1 );
		
		// ADD AGAIN
		$a->items[] = $b;
		$this->assertIdentical( $a->beforeAddCount, 1 );
		$this->assertIdentical( $a->afterAddCount, 1 );
		$this->assertIdentical( $b->beforeSetCount, 1 );
		$this->assertIdentical( $b->afterSetCount, 1 );
		
		
	}
	
	
	public function testLoad() {
		DomArOneToManyTestClass::getTable()->update();
	
		$a1 = new DomArOneToManyTestClass('a1');
		$a2 = new DomArOneToManyTestClass('a2');

		$b = new DomArOneToManyChildTestClass('b');
		$c = new DomArOneToManyChildTestClass('c');
		$d = new DomArOneToManyChildTestClass('d');
		$e = new DomArOneToManyChildTestClass('e');
		$f = new DomArOneToManyChildTestClass('f');
		$g = new DomArOneToManyChildTestClass('g');
		
		$a1->children[] = $b;
		$a1->children[] = $c;
		$a1->children[] = $d;
		
		$a1->aggrChildren[] = $c;
		$a1->aggrChildren[] = $d;
		$a1->aggrChildren[] = $e;
		
		$a1->parents[] = $d;
		$a1->parents[] = $e;
		$a1->parents[] = $f;
		
		$a2->parents[] = $g;
		
		$a1->save();
		$a2->save();
		
		// test find
		$this->assertIdentical( $a1->children->find( $b->id ), $b );
		$this->assertIdentical( $a1->aggrChildren->find( $c->id ), $c );
		$this->assertIdentical( $a1->parents->find( $d->id ), $d );
		$this->assertIdentical( $a1->children->find( $g->id ), false );
		
		// test query
		$children = $a1->children->query()->commit()->toArray();
		$this->assertIdentical( count($children), 3);
		$this->assertIdentical( $children[0], $b );
		$this->assertIdentical( $children[1], $c );
		$this->assertIdentical( $children[2], $d );
		
		$children = $a1->aggrChildren->query()->commit()->toArray();
		$this->assertIdentical( count($children), 3);
		$this->assertIdentical( $children[0], $c );
		$this->assertIdentical( $children[1], $d );
		$this->assertIdentical( $children[2], $e );
		
		$children = $a1->parents->query()->commit()->toArray();
		$this->assertIdentical( count($children), 3);
		$this->assertIdentical( $children[0], $d );
		$this->assertIdentical( $children[1], $e );
		$this->assertIdentical( $children[2], $f );
		
		// test data query
		$children = $a1->children->dataQuery()->commit()->toArray();
		$this->assertIdentical( count($children), 3);
		
		$this->assertEqual( $children[0]['id'], $b->id );
		$this->assertEqual( $children[1]['id'], $c->id );
		$this->assertEqual( $children[2]['id'], $d->id );
		
		$children = $a1->aggrChildren->dataQuery()->commit()->toArray();
		$this->assertIdentical( count($children), 3);
		$this->assertEqual( $children[0]['id'], $c->id );
		$this->assertEqual( $children[1]['id'], $d->id );
		$this->assertEqual( $children[2]['id'], $e->id );
		
		$children = $a1->parents->dataQuery()->commit()->toArray();
		$this->assertIdentical( count($children), 3);
		$this->assertEqual( $children[0]['id'], $d->id );
		$this->assertEqual( $children[1]['id'], $e->id );
		$this->assertEqual( $children[2]['id'], $f->id );
		
		
		// test id set query
		$children = $a1->children->idSetQuery()->commit()->toArray();
		$this->assertIdentical( count($children), 3);
		$this->assertEqual( $children[$b->id], $b->id );
		$this->assertEqual( $children[$c->id], $c->id );
		$this->assertEqual( $children[$d->id], $d->id );
		
		$children = $a1->aggrChildren->idSetQuery()->commit()->toArray();
		$this->assertIdentical( count($children), 3);
		$this->assertEqual( $children[$c->id], $c->id );
		$this->assertEqual( $children[$d->id], $d->id );
		$this->assertEqual( $children[$e->id], $e->id );
		
		$children = $a1->parents->idSetQuery()->commit()->toArray();
		$this->assertIdentical( count($children), 3);
		$this->assertEqual( $children[$d->id], $d->id );
		$this->assertEqual( $children[$e->id], $e->id );
		$this->assertEqual( $children[$f->id], $f->id );
		
		// test count
		$this->assertIdentical( $a1->children->count(), 3);
	
	}
	
	public function testSaveParent() {
		
		DomArOneToManyTestClass::getTable()->update();
		
		$a1 = new DomArOneToManyTestClass('a1');
		
		$b = new DomArOneToManyChildTestClass('b');
		$c = new DomArOneToManyChildTestClass('c');

		$a1->children[] = $b;
		$a1->children[] = $c;

		$b->save();
	
	}
	
	public function testOrdered() {
		
		// LISAMINE
		// listi uue lisamine
		// listi objekti lisamine mis juba on kuskil listis (Peaks aktiveeruma listist eemaldamine ja siis salvestatu lisamine)
		// listi salvestatu lisamine
		// alamale uue parent-i lisamine
		// 
		
		// KUSTUTAMINE
		// alama kustutamine
		// listi omaniku kustutamine
		// listist eemaldamine
		
		
		
		DomArOneToManyOrderedTestClass::getTable()->update();
	
		$p = new DomArOneToManyOrderedTestClass('m');
		$a = new DomArOneToManyOrderedChildTestClass('a');
		$b = new DomArOneToManyOrderedChildTestClass('b');
		$c = new DomArOneToManyOrderedChildTestClass('c');
		$d = new DomArOneToManyOrderedChildTestClass('d');
		
		$p->children[] = $a;
		$p->children[] = $b;
		$p->children[] = $c;
		$p->children[] = $d;
		
		$p->save();
		
		$order = $p->children->query()->orderBy('`order`')->commit()->toArray();
		$this->assertEqual( $order[0], $a );
		$this->assertEqual( $order[1], $b );
		$this->assertEqual( $order[2], $c );
		$this->assertEqual( $order[3], $d );
		
		$a->order->increase();
		
		$order = $p->children->query()->orderBy('`order`')->commit()->toArray();
		$this->assertEqual( $order[0], $b );
		$this->assertEqual( $order[1], $a );
		$this->assertEqual( $order[2], $c );
		$this->assertEqual( $order[3], $d );
		
		$c->order->decrease();
		
		$order = $p->children->query()->orderBy('`order`')->commit()->toArray();
		$this->assertEqual( $order[0], $b );
		$this->assertEqual( $order[1], $c );
		$this->assertEqual( $order[2], $a );
		$this->assertEqual( $order[3], $d );
		
		$b->order->increase();
		
		$order = $p->children->query()->orderBy('`order`')->commit()->toArray();
		$this->assertEqual( $order[0], $c );
		$this->assertEqual( $order[1], $b );
		$this->assertEqual( $order[2], $a );
		$this->assertEqual( $order[3], $d );
		
		$a->order->decrease();
		
		$order = $p->children->query()->orderBy('`order`')->commit()->toArray();
		$this->assertEqual( $order[0], $c );
		$this->assertEqual( $order[1], $a );
		$this->assertEqual( $order[2], $b );
		$this->assertEqual( $order[3], $d );
		
		
		
		$d->order->toMin();
		
		$order = $p->children->query()->orderBy('`order`')->commit()->toArray();
		$this->assertEqual( $order[0], $d );
		$this->assertEqual( $order[1], $c );
		$this->assertEqual( $order[2], $a );
		$this->assertEqual( $order[3], $b );
		
		$a->order->toMin();
		
		$order = $p->children->query()->orderBy('`order`')->commit()->toArray();
		$this->assertEqual( $order[0], $a );
		$this->assertEqual( $order[1], $d );
		$this->assertEqual( $order[2], $c );
		$this->assertEqual( $order[3], $b );
		
		
		
		$a->order->toMax();
		
		$order = $p->children->query()->orderBy('`order`')->commit()->toArray();
		$this->assertEqual( $order[0], $d );
		$this->assertEqual( $order[1], $c );
		$this->assertEqual( $order[2], $b );
		$this->assertEqual( $order[3], $a );

		$c->order->toMax();
		
		$order = $p->children->query()->orderBy('`order`')->commit()->toArray();
		$this->assertEqual( $order[0], $d );
		$this->assertEqual( $order[1], $b );
		$this->assertEqual( $order[2], $a );
		$this->assertEqual( $order[3], $c );
		
		
		$c->order->swap( $d );
		
		$order = $p->children->query()->orderBy('`order`')->commit()->toArray();
		$this->assertEqual( $order[0], $c );
		$this->assertEqual( $order[1], $b );
		$this->assertEqual( $order[2], $a );
		$this->assertEqual( $order[3], $d );
		
		$b->order->swap( $a );
		
		$order = $p->children->query()->orderBy('`order`')->commit()->toArray();
		$this->assertEqual( $order[0], $c );
		$this->assertEqual( $order[1], $a );
		$this->assertEqual( $order[2], $b );
		$this->assertEqual( $order[3], $d );
		
		
		/*
		$a->order = 2; // set new pos ($child->order->change(2))
		*/
		
		
		
	
	}
	
	public function testItemValidator() {
		
		$item = new DomArOneToManyVChild();
		$item->text = 'notMain';
		$ch = new DomArOneToManyVChild();
		$ch->text = 'good';

		$item->items[] = $ch;
		$this->assertFalse( $item->validated() );
		$this->assertEqual( $item->getValidationMessages(), array('I Only main is allowed, notMain was given') );

		$item->setValidated(true);
		$ch->setValidated(true);
		$ch->parent = $item;
		$this->assertFalse( $ch->validated() );
		$this->assertEqual( $ch->getValidationMessages(), array('P Only main is allowed, notMain was given') );
		
		$item->setValidated(true);	
		$ch->setValidated(true);
		$item->text = 'main';
		$ch->text = 'bad';
		$item->items[] = $ch;
		$this->assertFalse( $item->validated() );
		$this->assertEqual( $item->getValidationMessages(), array('I My error bad') );

		$item->setValidated(true);
		$ch->setValidated(true);
		$ch->parent = $item;
		$this->assertFalse( $ch->validated() );
		$this->assertEqual( $ch->getValidationMessages(), array('P My error bad') );
		
		$item->setValidated(true);
		$ch->setValidated(true);	
		$item->text = 'main';
		$ch->text = 'good';
		$item->items[] = $ch;
		$this->assertTrue( $item->validated() );
		
	}
	
	public function testListeners() {
		DomArOneToManyListener::getTable()->update();
		
		$a = new DomArOneToManyListener();
		$b = new DomArOneToManyListener();
		$c = new DomArOneToManyListener();
		$d = new DomArOneToManyListener();
		$e = new DomArOneToManyListener();
		
		// reset A
		$a->reset();
		$b->reset();
		$c->reset();
		$d->reset();
		$e->reset();
		$this->assertIdentical( $a->setValidator, 1 );
		$this->assertIdentical( $a->validator, 1 );
		$this->assertIdentical( $a->beforeAdd, 1 );
		$this->assertIdentical( $a->afterAdd, 1 );
		$this->assertIdentical( $a->beforeRemove, 1 );
		$this->assertIdentical( $a->afterRemove, 1 );
		$this->assertIdentical( $a->beforeSet, 1 );
		$this->assertIdentical( $a->afterSet, 1 );
		$this->assertIdentical( $a->setValidatorCount, 0 );
		$this->assertIdentical( $a->validatorCount, 0 );
		$this->assertIdentical( $a->beforeAddCount, 0 );
		$this->assertIdentical( $a->afterAddCount, 0 );
		$this->assertIdentical( $a->beforeRemoveCount, 0 );
		$this->assertIdentical( $a->afterRemoveCount, 0 );
		$this->assertIdentical( $a->beforeSetCount, 0 );
		$this->assertIdentical( $a->afterSetCount, 0 );
		
		
		// -------------------------------
		// ADD ITEM (unsaved)
		// -------------------------------
		$a->items[] = $b;
		$this->assertIdentical( $a->setValidator, 0 );
		$this->assertIdentical( $b->validator, 0 );
		$this->assertIdentical( $a->beforeAdd, 0 );
		$this->assertIdentical( $a->afterAdd, 0 );
		$this->assertIdentical( $b->beforeSet, 0 );
		$this->assertIdentical( $b->afterSet, 0 );
		
		$this->assertIdentical( $a->setValidatorCount, 1 );
		$this->assertIdentical( $a->validatorCount, 0 );
		$this->assertIdentical( $a->beforeAddCount, 1 );
		$this->assertIdentical( $a->afterAddCount, 1 );
		$this->assertIdentical( $a->beforeRemoveCount, 0 );
		$this->assertIdentical( $a->afterRemoveCount, 0 );
		$this->assertIdentical( $a->beforeSetCount, 0 );
		$this->assertIdentical( $a->afterSetCount, 0 );
		
		$this->assertIdentical( $b->setValidatorCount,0 );
		$this->assertIdentical( $b->validatorCount, 1 );
		$this->assertIdentical( $b->beforeAddCount, 0 );
		$this->assertIdentical( $b->afterAddCount, 0 );
		$this->assertIdentical( $b->beforeRemoveCount, 0 );
		$this->assertIdentical( $b->afterRemoveCount, 0 );
		$this->assertIdentical( $b->beforeSetCount, 1 );
		$this->assertIdentical( $b->afterSetCount, 1 );
		
		// -------------------------------
		// REMOVE ITEM (unsaved)
		// -------------------------------
		$a->reset();
		$b->reset();
		$a->items->remove( $b );
		$this->assertIdentical( $a->beforeRemove, 0 );
		$this->assertIdentical( $a->afterRemove, 0 );
		$this->assertIdentical( $b->beforeSet, 0 );
		$this->assertIdentical( $b->afterSet, 0 );
		$this->assertIdentical( $b->validator, 1 );
		
		$this->assertIdentical( $a->setValidatorCount, 0 );
		$this->assertIdentical( $a->validatorCount, 0 );
		$this->assertIdentical( $a->beforeAddCount, 0 );
		$this->assertIdentical( $a->afterAddCount, 0 );
		$this->assertIdentical( $a->beforeRemoveCount, 1 );
		$this->assertIdentical( $a->afterRemoveCount, 1 );
		$this->assertIdentical( $a->beforeSetCount, 0 );
		$this->assertIdentical( $a->afterSetCount, 0 );
		
		$this->assertIdentical( $b->setValidatorCount,0 );
		$this->assertIdentical( $b->validatorCount, 0 );
		$this->assertIdentical( $b->beforeAddCount, 0 );
		$this->assertIdentical( $b->afterAddCount, 0 );
		$this->assertIdentical( $b->beforeRemoveCount, 0 );
		$this->assertIdentical( $b->afterRemoveCount, 0 );
		$this->assertIdentical( $b->beforeSetCount, 1 );
		$this->assertIdentical( $b->afterSetCount, 1 );
		

		
		// -------------------------------
		// ADD ITEM (unsaved) (child side)
		// -------------------------------
		$a->reset();
		$c->parent = $a;
		
		$this->assertIdentical( $a->setValidator, 0 );
		$this->assertIdentical( $c->validator, 0 );
		$this->assertIdentical( $a->beforeAdd, 0 );
		$this->assertIdentical( $a->afterAdd, 0 );
		$this->assertIdentical( $c->beforeSet, 0 );
		$this->assertIdentical( $c->afterSet, 0 );
		
		$this->assertIdentical( $a->setValidatorCount, 1 );
		$this->assertIdentical( $a->validatorCount, 0 );
		$this->assertIdentical( $a->beforeAddCount, 1 );
		$this->assertIdentical( $a->afterAddCount, 1 );
		$this->assertIdentical( $a->beforeRemoveCount, 0 );
		$this->assertIdentical( $a->afterRemoveCount, 0 );
		$this->assertIdentical( $a->beforeSetCount, 0 );
		$this->assertIdentical( $a->afterSetCount, 0 );
		
		$this->assertIdentical( $c->setValidatorCount,0 );
		$this->assertIdentical( $c->validatorCount, 1 );
		$this->assertIdentical( $c->beforeAddCount, 0 );
		$this->assertIdentical( $c->afterAddCount, 0 );
		$this->assertIdentical( $c->beforeRemoveCount, 0 );
		$this->assertIdentical( $c->afterRemoveCount, 0 );
		$this->assertIdentical( $c->beforeSetCount, 1 );
		$this->assertIdentical( $c->afterSetCount, 1 );
		
		
		// -------------------------------
		// REMOVE ITEM (unsaved) (child side)
		// -------------------------------
		$a->reset();
		$c->reset();
		$c->parent = NULL;
		
		$this->assertIdentical( $a->beforeRemove, 0 );
		$this->assertIdentical( $a->afterRemove, 0 );
		$this->assertIdentical( $c->beforeSet, 0 );
		$this->assertIdentical( $c->afterSet, 0 );
		
		$this->assertIdentical( $a->setValidatorCount, 0 );
		$this->assertIdentical( $a->validatorCount, 0 );
		$this->assertIdentical( $a->beforeAddCount, 0 );
		$this->assertIdentical( $a->afterAddCount, 0 );
		$this->assertIdentical( $a->beforeRemoveCount, 1 );
		$this->assertIdentical( $a->afterRemoveCount, 1 );
		$this->assertIdentical( $a->beforeSetCount, 0 );
		$this->assertIdentical( $a->afterSetCount, 0 );
		
		$this->assertIdentical( $c->setValidatorCount,0 );
		$this->assertIdentical( $c->validatorCount, 1 );
		$this->assertIdentical( $c->beforeAddCount, 0 );
		$this->assertIdentical( $c->afterAddCount, 0 );
		$this->assertIdentical( $c->beforeRemoveCount, 0 );
		$this->assertIdentical( $c->afterRemoveCount, 0 );
		$this->assertIdentical( $c->beforeSetCount, 1 );
		$this->assertIdentical( $c->afterSetCount, 1 );
		
		
		
		// -------------------------------
		// ADD ITEM (saved)
		// -------------------------------
		$a->save();
		$d->save();
		$a->reset();
		$d->reset();
		$a->items[] = $d;
		
		$this->assertIdentical( $a->setValidator, 0 );
		$this->assertIdentical( $d->validator, 0 );
		$this->assertIdentical( $a->beforeAdd, 0 );
		$this->assertIdentical( $a->afterAdd, 0 );
		$this->assertIdentical( $d->beforeSet, 0 );
		$this->assertIdentical( $d->afterSet, 0 );
		
		$this->assertIdentical( $a->setValidatorCount, 1 );
		$this->assertIdentical( $a->validatorCount, 0 );
		$this->assertIdentical( $a->beforeAddCount, 1 );
		$this->assertIdentical( $a->afterAddCount, 1 );
		$this->assertIdentical( $a->beforeRemoveCount, 0 );
		$this->assertIdentical( $a->afterRemoveCount, 0 );
		$this->assertIdentical( $a->beforeSetCount, 0 );
		$this->assertIdentical( $a->afterSetCount, 0 );
		
		$this->assertIdentical( $d->setValidatorCount,0 );
		$this->assertIdentical( $d->validatorCount, 1 );
		$this->assertIdentical( $d->beforeAddCount, 0 );
		$this->assertIdentical( $d->afterAddCount, 0 );
		$this->assertIdentical( $d->beforeRemoveCount, 0 );
		$this->assertIdentical( $d->afterRemoveCount, 0 );
		$this->assertIdentical( $d->beforeSetCount, 1 );
		$this->assertIdentical( $d->afterSetCount, 1 );
		
		// -------------------------------
		// REMOVE ITEM (saved) (child side)
		// -------------------------------
		$a->reset();
		$d->reset();
		$a->items->remove( $d );
		
		$this->assertIdentical( $a->beforeRemove, 0 );
		$this->assertIdentical( $a->afterRemove, 0 );
		$this->assertIdentical( $d->beforeSet, 0 );
		$this->assertIdentical( $d->afterSet, 0 );
		
		$this->assertIdentical( $a->setValidatorCount, 0 );
		$this->assertIdentical( $a->validatorCount, 0 );
		$this->assertIdentical( $a->beforeAddCount, 0 );
		$this->assertIdentical( $a->afterAddCount, 0 );
		$this->assertIdentical( $a->beforeRemoveCount, 1 );
		$this->assertIdentical( $a->afterRemoveCount, 1 );
		$this->assertIdentical( $a->beforeSetCount, 0 );
		$this->assertIdentical( $a->afterSetCount, 0 );
		
		$this->assertIdentical( $d->setValidatorCount,0 );
		$this->assertIdentical( $d->validatorCount, 0 );
		$this->assertIdentical( $d->beforeAddCount, 0 );
		$this->assertIdentical( $d->afterAddCount, 0 );
		$this->assertIdentical( $d->beforeRemoveCount, 0 );
		$this->assertIdentical( $d->afterRemoveCount, 0 );
		$this->assertIdentical( $d->beforeSetCount, 1 );
		$this->assertIdentical( $d->afterSetCount, 1 );
		
		
		// -------------------------------
		// ADD ITEM (saved) (child side)
		// -------------------------------
		$e->save();
		$a->reset();
		$e->reset();
		$e->parent = $a;
		
		$this->assertIdentical( $a->setValidator, 0 );
		$this->assertIdentical( $e->validator, 0 );
		$this->assertIdentical( $a->beforeAdd, 0 );
		$this->assertIdentical( $a->afterAdd, 0 );
		$this->assertIdentical( $e->beforeSet, 0 );
		$this->assertIdentical( $e->afterSet, 0 );
		
		$this->assertIdentical( $a->setValidatorCount, 1 );
		$this->assertIdentical( $a->validatorCount, 0 );
		$this->assertIdentical( $a->beforeAddCount, 1 );
		$this->assertIdentical( $a->afterAddCount, 1 );
		$this->assertIdentical( $a->beforeRemoveCount, 0 );
		$this->assertIdentical( $a->afterRemoveCount, 0 );
		$this->assertIdentical( $a->beforeSetCount, 0 );
		$this->assertIdentical( $a->afterSetCount, 0 );
		
		$this->assertIdentical( $e->setValidatorCount,0 );
		$this->assertIdentical( $e->validatorCount, 1 );
		$this->assertIdentical( $e->beforeAddCount, 0 );
		$this->assertIdentical( $e->afterAddCount, 0 );
		$this->assertIdentical( $e->beforeRemoveCount, 0 );
		$this->assertIdentical( $e->afterRemoveCount, 0 );
		$this->assertIdentical( $e->beforeSetCount, 1 );
		$this->assertIdentical( $e->afterSetCount, 1 );
		
		// -------------------------------
		// REMOVE ITEM (saved) (child side)
		// -------------------------------
		$a->reset();
		$e->reset();
		$e->parent = NULL;
		
		$this->assertIdentical( $a->beforeRemove, 0 );
		$this->assertIdentical( $a->afterRemove, 0 );
		$this->assertIdentical( $e->beforeSet, 0 );
		$this->assertIdentical( $e->afterSet, 0 );
		
		$this->assertIdentical( $a->setValidatorCount, 0 );
		$this->assertIdentical( $a->validatorCount, 0 );
		$this->assertIdentical( $a->beforeAddCount, 0 );
		$this->assertIdentical( $a->afterAddCount, 0 );
		$this->assertIdentical( $a->beforeRemoveCount, 1 );
		$this->assertIdentical( $a->afterRemoveCount, 1 );
		$this->assertIdentical( $a->beforeSetCount, 0 );
		$this->assertIdentical( $a->afterSetCount, 0 );
		
		$this->assertIdentical( $e->setValidatorCount,0 );
		$this->assertIdentical( $e->validatorCount, 1 );
		$this->assertIdentical( $e->beforeAddCount, 0 );
		$this->assertIdentical( $e->afterAddCount, 0 );
		$this->assertIdentical( $e->beforeRemoveCount, 0 );
		$this->assertIdentical( $e->afterRemoveCount, 0 );
		$this->assertIdentical( $e->beforeSetCount, 1 );
		$this->assertIdentical( $e->afterSetCount, 1 );
	}

	public function testForeaching() {
		DomArOneToManyTestClass::getTable()->update();
		
		$a = new DomArOneToManyTestClass('a1');
		$b = new DomArOneToManyChildTestClass('b');
		$c = new DomArOneToManyChildTestClass('c');
		$d = new DomArOneToManyChildTestClass('d');
		$a->children[] = $b;
		$a->children[] = $c;
		

		// test foreaching without saving.
		$list = $a->children->toArray();

		$this->assertEqual( $list[0], $b );
		$this->assertEqual( $list[1], $c );
		$this->assertEqual( count($list), 2 );

		$list = array();
		foreach( $a->children as $child) $list[] = $child;
		$this->assertEqual( $list[0], $b );
		$this->assertEqual( $list[1], $c );
		$this->assertEqual( count($list), 2 );
		
		$list = $a->children->query()->commit()->toArray();
		$this->assertEqual( count($list), 0 );
	
		
		
		// test same when saved
		$a->save();
		$list = $a->children->toArray();
		$this->assertEqual( $list[0], $b );
		$this->assertEqual( $list[1], $c );
		$this->assertEqual( count($list), 2 );
		
		$list = array();
		foreach( $a->children as $child) $list[] = $child;
		$this->assertEqual( $list[0], $b );
		$this->assertEqual( $list[1], $c );
		$this->assertEqual( count($list), 2 );
		
		$list = $a->children->query()->commit()->toArray();
		$this->assertEqual( count($list), 2 );
		
		
		// test same when new child is added
		$a->children[] = $d;
		
		$list = $a->children->toArray();
		$this->assertEqual( $list[0], $b );
		$this->assertEqual( $list[1], $c );
		$this->assertEqual( $list[2], $d );
		$this->assertEqual( count($list), 3 );
		
		$list = array();
		foreach( $a->children as $child) $list[] = $child;
		$this->assertEqual( $list[0], $b );
		$this->assertEqual( $list[1], $c );
		$this->assertEqual( $list[2], $d );
		$this->assertEqual( count($list), 3 );
		
		$list = $a->children->query()->commit()->toArray();
		$this->assertEqual( count($list), 2 );
		
		
		
	}

	public function testJoinQuery() {
		DomArOneToManyTestClass::getTable()->update();
		
		$a1 = new DomArOneToManyTestClass('a1');

		$b = new DomArOneToManyChildTestClass('b');
		$c = new DomArOneToManyChildTestClass('c');

		$a1->children[] = $b;
		$a1->children[] = $c;

		$a1->save();
		
		DomAr::flushStoredObjects();
		$res = DomArOneToManyChildTestClass::query()->leftJoinProperty('parent','p')->commit()->toArray();
		
		// test that object exists in cache. If it does, then leftJoinProperty works.
		$this->assertTrue( $a1->id > 0 );
		$this->assertIdentical( DomAr::getObject($a1->id, 'DomArOneToManyTestClass')->id, $a1->id );
		
		
		
		
		$a1 = new DomArOneToManyTestClass('a1');

		$b = new DomArOneToManyChildTestClass('b');
		$c = new DomArOneToManyChildTestClass('c');

		$a1->parents[] = $b;
		$a1->parents[] = $c;

		$a1->save();
		
		DomAr::flushStoredObjects();
		$res = DomArOneToManyChildTestClass::query()->joinProperty('child','p')->commit()->toArray();
		
		// test that object exists in cache. If it does, then leftJoinProperty works.
		$this->assertTrue( $a1->id > 0 );
		$this->assertIdentical( DomAr::getObject($a1->id, 'DomArOneToManyTestClass')->id, $a1->id );
		
	}
	
}
?>